package tcp;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: fzykd
 * Date: 2022-10-26
 * Time: 17:53
 */

public class TcpEchoServer {
    //listen 英文原意 监听
    //private ServerSocket listenSocket = null;

    private ServerSocket serverSocket;

    //构造函数 指定运行端口
    public TcpEchoServer(int port) throws IOException {
        serverSocket = new ServerSocket(port);
    }

    public void start() throws IOException {
        System.out.println("服务器启动！");
        while (true){
            //由于TCP是有了链接的 不能一上来就读，而是先建立连接 (先接电话)
            //accept就是在接电话这个操作 前提是有人打了这个电话 没有人建立连接的话 那么就会阻塞
            //accept返回的是socket对象 称为clientSocket 后续和客户端之间的沟通 都是通过clientSocket来完成
            //serverSocket就干了一件事 接电话
            Socket clientSocket =  serverSocket.accept();
            
            processConnection(clientSocket);
            //过程 联系
        }
    }

    //这个方法 处理连接
    private void processConnection(Socket clientSocket) throws IOException {
        System.out.printf("[%s:%d] 客户端建立连接",clientSocket.getInetAddress().toString(),clientSocket.getPort());
        //接下来 处理请求 和 响应
        //这里针对 TCP socket的读写和文件读写一模一样
        try(InputStream inputStream = clientSocket.getInputStream()) {
            try (OutputStream outputStream = clientSocket.getOutputStream()){
                //循环的处理请求 分别返回响应
                Scanner scanner = new Scanner(inputStream);
                while (true){
                    //1.读取请求
                    //如果没有下一个结果 那么就结束循环
                    if (!scanner.hasNext()){
                        System.out.printf("[%s:%d] 客户端断开连接",clientSocket.getInetAddress().toString(),clientSocket.getPort());
                        break;
                    }
                    //此处使用Scanner更方便 如果不用 那么就要用原生的InputStream的read
                    String request = scanner.next();
                    //2.根据请求计算响应
                    String response = process(request);
                    //3.把响应返回给客户端
                    //方便
                    PrintWriter printWriter = new PrintWriter(outputStream);
                    printWriter.println(response);
                    //刷新缓冲区 如果没有这个刷新 可能客户端不能第一时间看到响应的结果
                    printWriter.flush();


                    System.out.printf("[%s:%d] req: %s,resp: %s\n",
                            clientSocket.getInetAddress().toString(),clientSocket.getPort(),request,response);

                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            //关闭资源
            clientSocket.close();
        }
    }

    private String process(String request) {
        return request;
    }

    public static void main(String[] args) throws IOException {
        TcpEchoServer server = new TcpEchoServer(9090);
        server.start();
    }
}
